#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <math.h>
#include <stdint.h>
#include "user.h"
#include "cloud.h"


// 完整的 `initialize_user` 函数
void initialize_user(User *u) {
    u->my_Hashtable = malloc(sizeof(HashTable));
    u->my_z_table = malloc(sizeof(z_table));
    u->my_o_table = malloc(sizeof(o_table));
    u->my_root_table = malloc(sizeof(roots_table));
    u->my_num_table = malloc(sizeof(num_table));
    u->my_o_hat_table = malloc(sizeof(o_hat_table));
    u->Px = malloc(sizeof(P_x));
    u->secret_share_table = malloc(sizeof(z_secret));
    u->my_w_table = malloc(sizeof(w_table));
    u->qtable = malloc(sizeof(q_table)); // 分配内存
    u->my_rie_table = malloc(sizeof(rie_table));

    // 初始化 qtable 中的元素为 0
    for (size_t i = 0; i < TABLE_SIZE; i++) {
        u->qtable->my_qtable[i] = malloc(sizeof(q_x));
        u->qtable->other_qtable[i] = malloc(sizeof(q_x));
        u->qtable->final_qtable[i] = malloc(sizeof(q_x));

        // 将每个 q_x 结构体的所有字段设置为 0
        memset(u->qtable->my_qtable[i], 0, sizeof(q_x));
        memset(u->qtable->other_qtable[i], 0, sizeof(q_x));
        memset(u->qtable->final_qtable[i], 0, sizeof(q_x));
    }

    // 其他初始化代码
    for (size_t i = 0; i < TABLE_SIZE; i++) {
        u->shuffle_lable_matrix[0][i] = i;
        u->shuffle_lable_matrix[1][i] = i;
    }

    for (int i = 0; i < TABLE_SIZE; i++) {
        u->my_Hashtable->HT[i] = malloc(sizeof(P_x));
        u->my_z_table->ztable[i] = malloc(sizeof(z_x));
        u->my_o_table->ox[i] = malloc(sizeof(o_x));
        u->my_root_table->r_table[i] = malloc(sizeof(roots));
        u->my_o_hat_table->ohat[i] = malloc(sizeof(o_x));
        u->my_rie_table->my_rie_table[i] = malloc(sizeof(rie_x));
        // u->qtable->my_qtable[i] = malloc(sizeof(q_x));
        // u->qtable->other_qtable[i] = malloc(sizeof(q_x));
        // u->qtable->final_qtable[i] = malloc(sizeof(q_x));
        u->other_zx[i] = malloc(sizeof(z_x));
        if (u->other_zx[i] == NULL) {
            fprintf(stderr, "Memory allocation failed for other_zx[%d]\n", i);
            exit(1);
        }
        for (int j = 0; j < 2; j++) {
            u->my_w_table->wx_table[j][i] = malloc(sizeof(w_x));
            u->secret_share_table->z_secret_table[j][i] = malloc(sizeof(z_x));
        }
    }
}


// 完整的 `initialize_cloud` 函数
void initialize_cloud(CloudServer *c) {
    c->cloud_w_table = malloc(sizeof(w_table));
    c->cloud_t_table = malloc(sizeof(t_table));

    // 初始化 cloud_t_table 中的元素为 0
    for (int i = 0; i < TABLE_SIZE; i++) {
        c->cloud_t_table->User_A_t_table[i] = malloc(sizeof(t_x));
        c->cloud_t_table->User_B_t_table[i] = malloc(sizeof(t_x));
        c->cloud_t_table->final_t_table[i] = malloc(sizeof(t_x));

        // 将每个 t_x 结构体的所有字段设置为 0
        memset(c->cloud_t_table->User_A_t_table[i], 0, sizeof(t_x));
        memset(c->cloud_t_table->User_B_t_table[i], 0, sizeof(t_x));
        memset(c->cloud_t_table->final_t_table[i], 0, sizeof(t_x));
    }

    for (int i = 0; i < USER_NUMBER; i++) {
        c->user_o_hat_table[i] = malloc(sizeof(o_hat_table));
        c->user_z_table[i] = malloc(sizeof(z_table));

        for (int j = 0; j < TABLE_SIZE; j++) {
            c->user_o_hat_table[i]->ohat[j] = malloc(sizeof(o_x));
            c->user_z_table[i]->ztable[j] = malloc(sizeof(z_x));
        }
    }

    for (int i = 0; i < TABLE_SIZE; i++) {
        c->cloud_t_table->User_A_t_table[i] = malloc(sizeof(t_x));
        c->cloud_t_table->User_B_t_table[i] = malloc(sizeof(t_x));
        c->cloud_t_table->final_t_table[i] = malloc(sizeof(t_x));

        // 将每个 t_x 结构体的所有字段设置为 0
        memset(c->cloud_t_table->User_A_t_table[i], 0, sizeof(t_x));
        memset(c->cloud_t_table->User_B_t_table[i], 0, sizeof(t_x));
        memset(c->cloud_t_table->final_t_table[i], 0, sizeof(t_x));

        for (int j = 0; j < 2; j++) {
            c->cloud_w_table->wx_table[j][i] = malloc(sizeof(w_x));
        }
    }
}

void free_user(User *u) {
    if (u == NULL) return;

    // 释放 my_Hashtable 中的每个 P_x 指针
    for (int i = 0; i < TABLE_SIZE; i++) {
        free(u->my_Hashtable->HT[i]);
    }
    free(u->my_Hashtable);

    // 释放 my_z_table 中的每个 z_x 指针
    for (int i = 0; i < TABLE_SIZE; i++) {
        free(u->my_z_table->ztable[i]);
    }
    free(u->my_z_table);

    // 释放 my_o_table 中的每个 o_x 指针
    for (int i = 0; i < TABLE_SIZE; i++) {
        free(u->my_o_table->ox[i]);
    }
    free(u->my_o_table);

    // 释放 my_root_table 中的每个 roots 指针
    for (int i = 0; i < TABLE_SIZE; i++) {
        free(u->my_root_table->r_table[i]);
    }
    free(u->my_root_table);

    // 释放 my_o_hat_table 中的每个 o_x 指针
    for (int i = 0; i < TABLE_SIZE; i++) {
        free(u->my_o_hat_table->ohat[i]);
    }
    free(u->my_o_hat_table);

    // 释放 my_rie_table 中的每个 rie_x 指针
    for (int i = 0; i < TABLE_SIZE; i++) {
        free(u->my_rie_table->my_rie_table[i]);
    }
    free(u->my_rie_table);

    // 释放 q_table 中的多项式指针
    for (int i = 0; i < TABLE_SIZE; i++) {
        free(u->qtable->my_qtable[i]);
        free(u->qtable->other_qtable[i]);
        free(u->qtable->final_qtable[i]);
    }
    free(u->qtable);

    // 释放 w_table 和 secret_share_table 中的二维数组
    for (int i = 0; i < TABLE_SIZE; i++) {
        for (int j = 0; j < 2; j++) {
            free(u->my_w_table->wx_table[j][i]);
            free(u->secret_share_table->z_secret_table[j][i]);
        }
    }
    free(u->my_w_table);
    free(u->secret_share_table);

    // 释放 Px 指针
    free(u->Px);

    // 释放 num_table
    free(u->my_num_table);
}


void free_cloud(CloudServer *c) {
    if (c == NULL) return;

    // 释放 user_o_hat_table 和 user_z_table 中的每个表
    for (int i = 0; i < USER_NUMBER; i++) {
        for (int j = 0; j < TABLE_SIZE; j++) {
            free(c->user_o_hat_table[i]->ohat[j]);
            free(c->user_z_table[i]->ztable[j]);
        }
        free(c->user_o_hat_table[i]);
        free(c->user_z_table[i]);
    }

    // 释放 cloud_w_table 中的二维数组
    for (int i = 0; i < 2; i++) {
        for (int j = 0; j < TABLE_SIZE; j++) {
            free(c->cloud_w_table->wx_table[i][j]);
        }
    }
    free(c->cloud_w_table);

    // 释放 cloud_t_table 中的 t_x 指针
    for (int i = 0; i < TABLE_SIZE; i++) {
        free(c->cloud_t_table->User_A_t_table[i]);
        free(c->cloud_t_table->User_B_t_table[i]);
        free(c->cloud_t_table->final_t_table[i]);
    }
    free(c->cloud_t_table);
}
